using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Be.Timvw.Framework.Domain.Specifications
{
    /// <summary>
    /// Specifications for the andspecfication.
    /// </summary>
    [TestClass]
    public class WhenTestingSatisfactionOfSpecificationAndSpecification
    {
        /// <summary>
        /// Should not be satisfied when atleast one specification is not satisfied.
        /// </summary>
        [TestMethod]
        public void ShouldNotBeSatisfiedWhenOneOfTheSpecificationsAreNotSatisfied()
        {
            ISpecification<int> specification = new AndSpecification<int>(new ISpecification<int>[]
            {
                new TrueSpecification<int>(),
                new FalseSpecification<int>()
            });

            Assert.IsFalse(specification.IsSatisfiedBy(0));
        }

        /// <summary>
        /// Should be satisfied when all specifications are satisfied.
        /// </summary>
        [TestMethod]
        public void ShouldBeSatisfiedWhenAllSpecificationsAreSatisfied()
        {
            ISpecification<int> specification = new AndSpecification<int>(new ISpecification<int>[]
            {
                new TrueSpecification<int>(),
                new TrueSpecification<int>()
            });

            Assert.IsTrue(specification.IsSatisfiedBy(0));
        }

        /// <summary>
        /// Should stop evaluating as soon as one specification is not satisified.
        /// </summary>
        [TestMethod]
        public void ShouldStopEvaluatingAsSoonAsOneSpecificationIsNotSatisfied()
        {
            // If the second specification is evaluated, it throws.
            ISpecification<string> specification = new AndSpecification<string>(new ISpecification<string>[]
            {
                new NotNullSpecification<string>(),
                new MoreThanThenCharactersSpecification()
            });

            Assert.IsFalse(specification.IsSatisfiedBy(null));
        }
    }
}